home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Snippets / QuickDraw / MakeIcon / IconUtil.c next >
Encoding:
C/C++ Source or Header  |  1992-07-15  |  7.3 KB  |  273 lines  |  [TEXT/KAHL]

  1. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2.     Routines to create icons of any pixel depth, and masked Icons.
  3.     By Brigham Stevens
  4.     Apple Computer Developer Technical Support
  5.   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  6.  
  7.  
  8. #include <QDOffscreen.h>
  9. #include <Palettes.h>
  10.  
  11. #include "IconUtil.h"
  12.  
  13. Handle MakeIconMask(GWorldPtr srcGWorld, Rect *srcRect, short iconSize)
  14. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  15.     this returns a handle to the image data for an icon MASK of dimension iconSize x iconSize.
  16.     The icon is created by copying the srcRect of srcGWorld into a PixMap.
  17.   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  18. {
  19.  
  20.     Handle    iconBits;
  21.     BitMap    srcBitMap,maskBitMap;
  22.     short    err;
  23.     long    numBytes;
  24.     short    rowbytes;
  25.     
  26.     iconBits = MakeIcon(srcGWorld, srcRect, 1, iconSize);
  27.     if(!iconBits)    return NIL;
  28.     HLock(iconBits);
  29.  
  30.     srcBitMap.bounds = *srcRect;            // set up a plain jane bitmap
  31.     srcBitMap.rowBytes = iconSize/8;
  32.     srcBitMap.baseAddr = *iconBits;
  33.     
  34.     NewMaskedBitMap(&srcBitMap,&maskBitMap,srcRect);
  35.     if(!maskBitMap.baseAddr)
  36.     {
  37.         DisposHandle(iconBits);
  38.         return NIL;
  39.     }
  40.     
  41.     HUnlock(iconBits);
  42.  
  43.     CalcOffScreen(srcRect,&numBytes,&rowbytes);
  44.     err = PtrToXHand(maskBitMap.baseAddr,iconBits,numBytes);
  45.     if(err)
  46.     {
  47.         /* we can at least return a handle to the original image,
  48.             which may be considered better than nothing.
  49.             OR - we can dump the image and return NIL.
  50.         */
  51.         DebugStr("\pERror in PtrToXHand");
  52.     }
  53.     
  54.     FreeBitMap(&maskBitMap);
  55.  
  56.     HNoPurge(iconBits);
  57.     return iconBits;
  58. }
  59.  
  60.  
  61. Handle    MakeICN_pound(GWorldPtr    gwp, Rect *srcRect, short iconDimension)
  62. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  63.     this returns a handle to the image data for an icon and it's mask, of size iconDimension x iconDimension.
  64.     The icon is created by copying the srcRect of srcGWorld into a PixMap.
  65.   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  66. {
  67.  
  68.     Handle    icon;
  69.     Handle    iconMask;
  70.     Size    iconSize;
  71.     
  72.     icon = MakeIcon(gwp, srcRect,1,iconDimension);            
  73.     
  74.     if(icon)
  75.     {
  76.         iconMask = MakeIconMask(gwp, srcRect, iconDimension);    
  77.         
  78.         if(iconMask)
  79.         {
  80.             iconSize = GetHandleSize(icon);
  81.             SetHandleSize(icon, iconSize + GetHandleSize(iconMask));
  82.             CheckError("\pSetHandleSize fail.",MemError());
  83.             BlockMove(*iconMask, (Ptr)(((long)*icon) + iconSize), GetHandleSize(iconMask));            
  84.             DisposHandle(iconMask);
  85.         }
  86.  
  87.     }
  88.     
  89.     return icon;
  90.  
  91. }
  92.  
  93. Handle MakeIcon(GWorldPtr srcGWorld, Rect *srcRect, short dstDepth, short iconSize)
  94. /*
  95.     Creates a handle to the image data for an icon, or NIL if an error.
  96.     The source image is specified by GWorld and regtangle defining the area
  97.     to create the icon from.
  98.     The type of icon is specified by the depth and Size paramters.
  99.     iconSize is used for both height and width.
  100.     For example, to create an Icl8 pass 8 for dstDepth and 32 for iconSize.
  101.     to create an ics8 pass 8 for the dstDepth and 16 for iconSize.
  102.     to create an ICON pass 1 for the dstDepth and 32 for iconSize.
  103.     
  104.     
  105. */
  106. {
  107.     GWorldPtr        saveWorld;
  108.     GDHandle        saveHandle;
  109.     long            bytesPerRow;
  110.     long            imageSize;
  111.     Handle            dstHandle;
  112.     PixMapHandle    pix;
  113.     Rect            iconFrame;
  114.     QDErr            err;
  115.     
  116.     GetGWorld(&saveWorld,&saveHandle);        // save Graphics env state
  117.  
  118.     SetGWorld(srcGWorld,NIL);
  119.     
  120.     iconFrame.top = 0;
  121.     iconFrame.left = 0;
  122.     iconFrame.bottom = iconSize;
  123.     iconFrame.right = iconSize;
  124.     
  125.     // make a gworld for the icl resource
  126.     pix = NewHandle(sizeof(PixMap));
  127.     
  128.     /* See Tech Note #120 - for info on creating a PixMap by hand as SetUpPixMap
  129.         does.  SetUpPixMap was taken from that Tech Note....
  130.     */
  131.     err =  SetUpPixMap(dstDepth,&iconFrame,GetCTable(dstDepth),pix);
  132.  
  133.     if(err)
  134.     {
  135.         asm {move.w    err, d0 }
  136.         DebugStr("\pQuickDraw error.  see d0 for code....");
  137.         return NIL;
  138.     }
  139.         
  140.     LockPixels(GetGWorldPixMap(srcGWorld));
  141.     LockPixels(pix);
  142.             
  143.     CopyBits(*srcGWorld->portPixMap,
  144.                 *pix,
  145.                 srcRect,
  146.                 &iconFrame,
  147.                 srcCopy | ditherCopy, NIL);
  148.  
  149.  
  150.     UnlockPixels(GetGWorldPixMap(srcGWorld));
  151.  
  152.      bytesPerRow = ((dstDepth * ((**pix).bounds.right - (**pix).bounds.left) + 31) / 32) * 4;
  153.     imageSize  = (bytesPerRow) * ((**pix).bounds.bottom - (**pix).bounds.top);
  154.  
  155.     dstHandle = NewHandle(imageSize);
  156.     err = MemError ();
  157.     if(err || dstHandle == nil)
  158.     {
  159.         asm { move.w err, d0}
  160.         DebugStr("\pI am fuckered.");
  161.         return NIL;    
  162.     }
  163.     HLock(dstHandle);
  164.     BlockMove(GetPixBaseAddr(pix),*dstHandle,imageSize);
  165.     HUnlock(dstHandle);
  166.     UnlockPixels(pix);
  167.     TearDownPixMap(pix);
  168.     // Restore graphics env to previous state
  169.     SetGWorld(saveWorld,saveHandle);
  170.     
  171.     HNoPurge(dstHandle);
  172.     return dstHandle;
  173. }
  174.  
  175.  
  176. void TearDownPixMap(PixMapHandle pix)
  177. {
  178.     // We really need to do more....  BUT It is the thought that counts.. 
  179.     DisposHandle(pix);    
  180. }
  181.  
  182.  
  183. #include <QDOffscreen.h>
  184. #include <Palettes.h>
  185.  
  186. PicHandle PIXtoPICT(CGrafPtr wp)
  187. {
  188.     PicHandle        pict;                // this is the Picture we give back
  189.     WindowPtr        saveWindow;            // for saving the port
  190.     
  191.     GetPort(&saveWindow);                // set up the ports so we can 
  192.     SetPort(wp);                        //  - copy and have a palette too
  193.  
  194.     pict = OpenPicture(&wp->portRect);    // open a picture, this disables drawing
  195.     if(!pict)    return NIL;
  196.     
  197.     CopyBits(*wp->portPixMap,            // src PixMap    - we copy image over itself -
  198.                 *wp->portPixMap,        // dst PixMap    - no drawing occurs -
  199.                 &wp->portRect,            // srcRect        - it will be recorded and compressed -
  200.                 &wp->portRect,            // dstRect        - into the picture that is open -
  201.                 srcCopy,NIL);            // copyMode and no clip region
  202.  
  203.     ClosePicture();                        // We are done recording the picture
  204.     SetPort(saveWindow);                // restore to the previous port
  205.     return pict;                        // return our groovy pict handle
  206. }
  207.  
  208. GWorldPtr LoadPictToGWorld(int resID, WindowPtr wp, int numEntries,
  209.                         int pdepth, int gdepth, Boolean linkCtabToPal)
  210.                         
  211. /*
  212.     Loads in the picture specified be the resID parameter.
  213.     Creates a GWorld from characteristics of window wp
  214.     Stores the GWorld pointer in the wRefcon field of the windowRecord.
  215. */
  216. {
  217.  
  218.     CTabHandle        gwctab;
  219.     WindowPtr        saveWindow;
  220.     GDHandle        saveDevice;
  221.     PicHandle        pict;
  222.     Rect            destRect;
  223.     short            i;
  224.     PaletteHandle     pal;
  225.     GWorldPtr         gw;    
  226.  
  227.     pict = GetPicture(resID);
  228.     if(!pict)
  229.         DebugStr("\pError - pict was NIL!");
  230.     destRect = (**pict).picFrame;
  231.     OffsetRect( &destRect, -destRect.left, -destRect.top );
  232.     SizeWindow(wp, destRect.right, destRect.bottom,true);
  233.  
  234.     pal = NewPalette(numEntries, GetCTable(pdepth), pmTolerant, 0);
  235.     SetPalette(wp, pal, true);
  236.  
  237.     gw = (GWorldPtr)CreateOffScreen(wp, gdepth, false);    // make a gworld
  238.  
  239.     if(linkCtabToPal)
  240.     {
  241.         gwctab = (**GetGWorldPixMap(gw)).pmTable;    // get the color table for the gWorld.
  242.     
  243.         // Set up the clut so that the entries refer to palette
  244.         // indexes, instead of the usual rgb information.
  245.         (**gwctab).ctFlags |= 0x4000;        // this bit is the flag to indicate this
  246.         //•••••••• See Inside Macintosh Volume VI page 20-17
  247.         
  248.         for (i = 0; i <= (**gwctab).ctSize; i++)
  249.         {
  250.             (**gwctab).ctTable[i].value = i;
  251.         }
  252.         CTabChanged(gwctab);        // Update the color table
  253.     }    
  254.     
  255.     GetGWorld(&saveWindow,&saveDevice);
  256.     SetGWorld(gw,nil);
  257.  
  258.     // draw the picture into the offscreen gworld
  259.     pict = GetPicture(resID);
  260.     
  261.     if(LockPixels (GetGWorldPixMap (gw)))
  262.     {
  263.         DrawPicture(pict,&destRect);
  264.         UnlockPixels(GetGWorldPixMap(gw));
  265.     }
  266.     SetGWorld(saveWindow,saveDevice);
  267.     SetWRefCon(wp,(long)gw);                    // store gWold in refcon of Window
  268.     ReleaseResource(pict);
  269.     
  270.     return gw;
  271. }
  272.  
  273.